package lt.ntec.danblog.server.blog.model.objectify;

import com.google.appengine.api.datastore.Entity;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.Transient;
import lt.ntec.danblog.server.blog.model.Post;
import lt.ntec.danblog.server.core.model.Comment;
import lt.ntec.danblog.server.core.model.Commentable;
import lt.ntec.danblog.server.core.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class BlogComment implements Comment {
    
    private static final Logger LOG = LoggerFactory.getLogger(BlogComment.class);

    @Id
    private Long id;
    
    @Transient
    private User user;
    
    private Long userId;
    
    private Key<Commentable> parentKey;
    
    @Transient
    private Post parent;
    private String content;
    private Date date;
    private int voteDown;
    private int voteUp;
    
    private Set<Long> votedUsers = new HashSet<Long>();
    
    public BlogComment() {
        
    }
    
    public BlogComment(User user, Post parent) {
        this.user = user;
        this.parent = parent;
    }

    @Override
    public User getUser() {
        return user;
    }

    @Override
    public String getContent() {
        return content;
    }

    @Override
    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public Date getDate() {
        return date;
    }

    @Override
    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public Post getParent() {
        return parent;
    }

    @Override
    public int getVoteUp() {
        return voteUp;
    }

    @Override
    public int getVoteDown() {
        return voteDown;
    }

    @Override
    public void addVoteDown(User user) {
        voteDown++;
        votedUsers.add(user.getId());
    }

    @Override
    public void addVoteUp(User user) {
        voteUp++;
        votedUsers.add(user.getId());
    }

    @Override
    public boolean hasUserVoted(User user) {
        if(votedUsers.contains(user.getId())) {
            return true;
        }
        return false;
    }

    @Override
    public Long getId() {
        return id;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Key<Commentable> getParentKey() {
        return parentKey;
    }

    public void setParentKey(Key<Commentable> parentKey) {
        this.parentKey = parentKey;
    }
    
    @PostLoad
    void load(Objectify ofy, Entity ent) {
        LOG.debug("applying userProxy for " + getId());
        this.parent = ProxyFactory.getInstance().getPostProxy(this);
        
        this.user = ProxyFactory.getInstance().getCommentUserProxy(this);
        
    }
    
    @PrePersist
    void persist(Objectify ofy, Entity ent) {
        if (parent == null) {
            throw new IllegalStateException("Parent should be defined");
        }
        
        if (parent.getId() == null) {
            throw new IllegalStateException("Parent should be saved");
        }
        
        if (user.getId() == null) {
            throw new IllegalStateException("User should be saved");
        }
        
        if (parentKey == null) {
            this.parentKey = new Key<Commentable>(parent.getClass(), parent.
                    getId());
        }
        
        if (userId == null) {
            this.userId = user.getId();
        }
    }
    
}
